package com.suoluo.zenapp.common.file;

import java.io.File;
import java.io.IOException;
import java.util.Random;

import org.springframework.web.multipart.MultipartFile;

import com.suoluo.zenapp.common.Application;
import com.suoluo.zenapp.common.config.SystemConfigHolder;
import com.suoluo.zenapp.common.encrypt.EncryptUtil;

public final class UploadImageManager {

	// 新闻每10天生成一个目录
	// private static long TEN_MILLIS = 10 * 24 * 60 * 60 * 1000;
	/**
	 * 默认文件名生成器，取用当前时间的毫秒数
	 */
	private static FileNameGenerator DEFAULT_FILE_NAME_GENERATOR = new SystemMillsNameGenerator();

	public static String IMAGE_PATH = "/upload/images/";

	private UploadImageManager() {

	}

	public static interface FileNameGenerator {
		String generate(MultipartFile mfile);
	}

	private static class SystemMillsNameGenerator implements FileNameGenerator {

		private static String[] chars = new String[] { // 要使用生成URL的字符
		"a", "b", "c", "d", "e", "f", "g", "h", "i", "j", "k", "l", "m", "n",
				"o", "p", "q", "r", "s", "t", "u", "v", "w", "x", "y", "z",
				"0", "1", "2", "3", "4", "5", "6", "7", "8", "9", "A", "B",
				"C", "D", "E", "F", "G", "H", "I", "J", "K", "L", "M", "N",
				"O", "P", "Q", "R", "S", "T", "U", "V", "W", "X", "Y", "Z" };
		private final Random rand = new Random();

		@Override
		public String generate(MultipartFile mfile) {
			String suffix = FileUtils.parseFileNameSuffix(mfile
					.getOriginalFilename());
			String fileName = shortText(mfile.getOriginalFilename()) + suffix;
			return fileName;
		}

		public String shortText(String string) {
			// String key = "XuLiang"; //自定义生成MD5加密字符串前的混合KEY

			String hex = EncryptUtil.md5(System.currentTimeMillis() + string);
			// int hexLen = hex.length();
			// int subHexLen = hexLen / 8;
			// String[] ShortStr = new String[4];
			int offset = rand.nextInt(4);
			// for (int i = 0; i < subHexLen; i++) {
			StringBuilder text = new StringBuilder(6);
			int j = offset + 1;
			String subHex = hex.substring(offset * 8, j * 8);
			long idx = Long.valueOf("3FFFFFFF", 16) & Long.valueOf(subHex, 16);

			for (int k = 0; k < 6; k++) {
				int index = (int) (Long.valueOf("0000003D", 16) & idx);
				text.append(chars[index]);
				idx = idx >> 5;
			}
			return text.toString();
		}
	}

	/**
	 * 保存目的地资源图片
	 * 
	 * @param request
	 *            请求
	 * @param fileKey
	 *            文件关联的属性name
	 * @return String 返回保存后的路径
	 */
	public static FileEntry saveDestResourceImg(MultipartFile mfile, int destId) {
		String path = destImgPath(destId);
		return saveImg(mfile, path, DEFAULT_FILE_NAME_GENERATOR);
	}

	private static String destImgPath(int destId) {
		StringBuilder path = new StringBuilder("dest/");
		path.append(destId).append("/");

		return path.toString();
	}

	private static FileEntry saveImg(MultipartFile mfile, String relativePath,
			FileNameGenerator generator) {
		if (mfile == null || mfile.getSize() == 0) {
			return null;
		}

		// String relativeDir = SystemConfigHolder.getRelativeUploadImageRoot()
		// + relativePath;
		StringBuilder imgPath = new StringBuilder(IMAGE_PATH);
		imgPath.append(relativePath);
		Application a = Application.getInstance();
		String path = a.getPath("/") + imgPath;
		// 验证当前路径是否存在
		File saveDir = new File(path);
		if (!saveDir.exists()) {
			if (!saveDir.mkdirs()) {
				throw new RuntimeException("fail to mkdirs,path=" + path);
			}
		}
		if (generator == null) {
			generator = DEFAULT_FILE_NAME_GENERATOR;
		}
		// 生成文件名称
		String fileName = generator.generate(mfile);

		// 保存图片
		String filePath = path + fileName;
		// 保存图片
		FileUtils.saveFile(filePath, mfile);
		FileEntry entry = new FileEntry(relativePath, fileName);
		return entry;
	}

	/**
	 * 获取图片上传的相对根目录，即没有“/”
	 */
	public static String getRelativeUploadImageRoot() {
		String root = "/upload/images";
		if (root.startsWith("/")) {
			root = root.substring(1);
		}
		return root;
	}

	/**
	 * 删除文件
	 * 
	 * @param request
	 * @param filePath
	 */
	public static void deleteFile(FileEntry entry) {
		if (entry == null) {
			return;
		}
		Application a = Application.getInstance();
		String path = a.getPath("/") + IMAGE_PATH + entry.getFilePath();
		File file = new File(path);
		//删除大图
		if (file.exists() && file.isFile()) {
			if (!file.delete()) {
				throw new RuntimeException("fail to delete img,filePath = "
						+ path);
			}
		} 
		String miniPath = a.getPath("/")+ IMAGE_PATH +entry.getMiniFilePath();
		File miniFile = new File(miniPath);
		//删除小图
		if (miniFile.exists() && miniFile.isFile()) {
			if (!miniFile.delete()) {
				throw new RuntimeException("fail to delete img,filePath = "
						+ miniPath);
			}
		} else {
			// 如果文件不存在则直接返回
			return;
		}
		// 如果父目录是空的需要删除该目录
		File parentDir = file.getParentFile();
		if (parentDir.listFiles() != null) {
			while (parentDir.listFiles().length == 0) {
				parentDir.delete();
				parentDir = parentDir.getParentFile();
			}
		}
	}

	public static FileEntry replaceFile(MultipartFile multipartFile,
			String oldImgUrl, int destId) {

		FileEntry newEntry = saveDestResourceImg(multipartFile, destId);
		if (newEntry == null) {
			return null;
		} else {
			FileEntry oldEntry = new FileEntry(oldImgUrl);
			// 删除原有图片
			deleteFile(oldEntry);
			// 返回新图片
			return newEntry;
		}

	}
	/**
	 * 保存图片，并压缩生成小图片
	 * @param mfile
	 * @param destId
	 * @return
	 */
	public static FileEntry saveDestMiniImg(MultipartFile mfile,int destId)
	{
		String path = destImgPath(destId);
		return saveImgAndGenerateMiniImg(mfile,
				path, DEFAULT_FILE_NAME_GENERATOR, SystemConfigHolder.getSystemImgBlockWidth(),
				SystemConfigHolder.getSystemImgBlockHeight());
	}
//	/**
//	 * 保存大图，并且生成小图
//	 * 
//	 * @param request
//	 * @param fileKey
//	 * @param relativePath
//	 * @param generator
//	 * @return
//	 */
//	private static FileEntry saveResourceMiniImg(MultipartFile mfile,
//			String relativePath, FileNameGenerator generator, int miniImgWidth,
//			int miniImgHeight) {
//
//		if (mfile == null || mfile.getSize() == 0) {
//			return null;
//		}
//		Application a = Application.getInstance();
//		String path = a.getPath("/") + relativePath;
//		// 验证当前路径是否存在
//		File saveDir = new File(path);
//		if (!saveDir.exists()) {
//			if (!saveDir.mkdirs()) {
//				throw new RuntimeException("fail to mkdirs,path="
//						+ path);
//			}
//		}
//		if (generator == null) {
//			generator = DEFAULT_FILE_NAME_GENERATOR;
//		}
//		// 生成文件名称
//		String fileName = SystemConfigHolder.getMiniImgPreffix()+generator.generate(mfile);
//
//		// 保存图片
//		String filePath = path + fileName;
//		File origiFile = new File(filePath);
//		// 保存大图，生成小图
//		try {
//			FileUtils.writeFile(origiFile, mfile.getInputStream());
//			// 迷你小图的路径
//			String miniFilePath = path+ fileName;
//			File outputMiniFile = new File(miniFilePath);
//			ImageUtils.compressImage(origiFile, outputMiniFile,
//					miniImgHeight, miniImgWidth);
//			// relativePath必须要有“/”
//			FileEntry entry = new FileEntry(relativePath, fileName);
//			return entry;
//		} catch (IOException e) {
//			if (origiFile.exists()) {
//				origiFile.delete();
//			}
//			throw new RuntimeException(
//					"fail to compress img,(mfile.getInputStream())", e);
//		}
//	}
	/**
	 * 保存大图，并且生成小图
	 * 
	 * @param request
	 * @param fileKey
	 * @param relativePath
	 * @param generator
	 * @return
	 */
	private static FileEntry saveImgAndGenerateMiniImg(MultipartFile mfile,
			String relativePath, FileNameGenerator generator, int miniImgWidth,
			int miniImgHeight) {

		if (mfile == null || mfile.getSize() == 0) {
			return null;
		}

		Application a = Application.getInstance();
		String abstractDirPath = a.getPath("/") +IMAGE_PATH+ relativePath;

		// 验证当前路径是否存在
		File saveDir = new File(abstractDirPath);
		if (!saveDir.exists()) {
			if (!saveDir.mkdirs()) {
				throw new RuntimeException("fail to mkdirs,path="
						+ abstractDirPath);
			}
		}
		if (generator == null) {
			generator = DEFAULT_FILE_NAME_GENERATOR;
		}
		// 生成文件名称
		String fileName = generator.generate(mfile);

		// 保存图片
		String filePath = abstractDirPath + fileName;
		File origiFile = new File(filePath);
		// 保存大图，声称小图
		try {
			FileUtils.writeFile(origiFile, mfile.getInputStream());
			// 迷你小图的路径
			String miniFilePath = abstractDirPath + SystemConfigHolder.getMiniImgPreffix() + fileName;
			File outputMiniFile = new File(miniFilePath);
			ImageUtils.compressImage(origiFile, outputMiniFile,
					miniImgHeight, miniImgWidth);
			// relativePath必须要有“/”
			FileEntry entry = new FileEntry(relativePath, fileName);
			return entry;
		} catch (IOException e) {
			if (origiFile.exists()) {
				origiFile.delete();
			}
			throw new RuntimeException(
					"fail to compress img,(mfile.getInputStream())", e);
		}
	}
	
	/**
	 * 替换图片和图片的小图片
	 * 
	 * @param request
	 * @param oldEntry
	 * @param fileKey
	 * @return
	 */
	public static FileEntry replaceImgAndMiniImg(MultipartFile mfile,
			FileEntry oldEntry) {
		FileEntry entry = saveImgAndGenerateMiniImg(mfile,
				oldEntry.getFilePreffix(), DEFAULT_FILE_NAME_GENERATOR,
				SystemConfigHolder.getSystemImgBlockWidth(),
				SystemConfigHolder.getSystemImgBlockHeight());
		//没有替换文件，则不需要删除
		if (entry != null){
			deleteFile(oldEntry);
		}
		return entry;
	}
}
